home *** CD-ROM | disk | FTP | other *** search
-
- SiFLyiNG
- Tutorial #7
-
- ____________________________________________________________________________
-
- Target : ---===<<Crackme 1 by VisionZ>>===---
- d/l it on EB site : http://crackmes.cjb.net
- Protection type : Serial/Name
- Level : not too easy, not too hard
- Tools needed : SoftIce 3.xx
- Basis of cracking
- A brain
- Punk music
- Liters of beer
- I think that's enough ;)
-
- ____________________________________________________________________________
-
- Before beginning...
-
- This crackme is based on a serial/name protection. But the serial is
- not calculated from the original name. The name is slightly transformed, so
- that he contains only caracters between A and Z so it's transformed in upper
- case too. There are no obvious comparisons, but we can calculate the valid
- serial char per char with some simple equation... but you'll see :)
- Time is money so let's start...
-
- ____________________________________________________________________________
-
- The essay...
-
-
- You have to enter the name and serial in a TextBox. I put 'SiFLyiNG'
- as name and '12345678' as serial. Then let's bpx on hmemcpy in SoftIce
- and exit the debugger. There press the 'Check!' button and Boom you're back
- in SoftIce. There are two entries so press F5, so that the prog will get the
- serial. Then press F11 to return to the caller and F12 till you see :
-
- CRACKME 1!.text+XXXX at the bottom of the code window.
-
- There you see this first piece of code:
-
- :004011DF push ecx ;'d ecx' and you'll see the entered code
- :004011E0 lea edx, dword ptr [esp+14]
- :004011E4 mov ecx, esp
- :004011E6 mov dword ptr [esp+1C], esp
- :004011EA push edx
- :004011EB Call 004016CA
- :004011F0 lea eax, dword ptr [esp+1C]
- :004011F4 mov ecx, ebp
- :004011F6 push eax
- :004011F7 call 004013D0 ; this call will transforms the name and will keep
- ; only characters between A and Z or a and z. Moreover, it will
- ; convert the transformed name to uppercase, i.e. 'SiFLyiNG' becomes
- ; 'SIFLYING' and '123 <sErIaL> >=-' becomes 'SERIAL'.
- :004011FC push eax
- :004011FD lea ecx, dword ptr [esp+14]
- :00401201 mov [esp+28], 02
- :00401206 Call 004016C4
- :0040120B lea ecx, dword ptr [esp+18]
- :0040120F mov [esp+24], 01
- :00401214 Call 004016BE
- :00401219 mov ecx, dword ptr [esp+10] ; ECX points to the transformed name
- :0040121D mov edx, dword ptr [esp+14] ; EDX points to the serial
- :00401221 mov eax, dword ptr [ecx-08] ; EAX = lenght of transformed name
- :00401224 mov ecx, dword ptr [edx-08] ; ECX = lenght of serial
- :00401227 cmp eax, ecx ; comparison between the two lenghts
- :00401229 jne 0040135B ;if len code and len name aren't equal => bad guy
- :0040122F cmp eax, 00000003 ; the lenght of the transformed code must be > 2
- :00401232 jl 0040135B ; otherwise => bad cracker
- :00401238 push eax
- :00401239 Call 004016B8
- :0040123E mov esi, eax
- :00401240 mov eax, dword ptr [esp+14]
- :00401244 add esp, 00000004
- :00401247 xor ecx, ecx
- :00401249 mov edx, dword ptr [eax-08]
- :0040124C dec edx
- :0040124D test edx, edx
- :0040124F jle 00401288
-
- Oufff in my case i'm lucky because the entered name ('SiFLyiNG') and
- the entered serial ('12345678') have the same lenght so it won't jump to the
- bad cracker routine at 401229 and it won't jump at 401232 anymore. So we can
- trace on to the calculation/comparison routine of the serial. But let's
- remember that EAX points to the transformed name: 'SIFLYING'. Here begins
- a loop depending on the lenght of the transformed code:
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00401286(C)
- |
- :00401251 mov dl, byte ptr [ecx+eax] ;dl=ASCII code of char(ECX)of name
- :00401254 mov bl, byte ptr [ecx+eax+01] ;bl=ASCII code of the next char
- :00401258 mov eax, dword ptr [esp+14] ;eax points to the serial
- :0040125C movsx edx, dl ;edx=ASCII code of char(ECX) of name
- :0040125F movsx eax, byte ptr [ecx+eax] ;eax=ASCII code of char(ECX) of serial
- :00401263 lea eax, dword ptr [eax+edx-02] ;eax=eax+edx-2
- :00401267 cdq ;convert dword to quadword and edx=0
- :00401268 sub eax, edx ;eax=eax-edx=eax-0=eax each time
- :0040126A movsx edx, bl ;adx=bl
- :0040126D sar eax, 1 ;eax=eax/2
- :0040126F inc eax ;eax = eax +1
- :00401270 sub edx, 00000002 ;edx = edx -2
- :00401273 cmp eax, edx ;eax and edx must be equal
- :00401275 sete al ;al=1 if equal (bad if al=0)
- :00401278 mov byte ptr [ecx+esi], al ;stores al in an array
- :0040127B mov eax, dword ptr [esp+10] ;eax points to the name
- :0040127F inc ecx ;increases the counter
- :00401280 mov edx, dword ptr [eax-08] ;edx = len of transformed name
- :00401283 dec edx ;decreases edx => edx=edx-1
- :00401284 cmp ecx, edx ;while ecx<>len of name -1
- :00401286 jl 00401251 ;keeps on the loop
-
- This loop is really important because it will allow us to find the
- first part of the good serial.
- It depends on the lenght of the name - 1. So it will loop 8-1=7 times
- for 'SIFLYING'.
- Let's summarize what happens: (TName = transformed name)
-
- ecx=(ASCII code of the char(ECX) of the TName + ASCII code of the
- char(ECX) of the entered serial - 2) / 2 + 1
-
- edx=ASCII code of the char(ECX+1) of the TName - 2
-
- And we should have: ecx=edx
- so if N1N2N3N4N5N6N7N8 are the ascii code of the characters of the TName
- and S1S2S3S4S5S6S7S8 the ascii code of the characters of the Serial
- then we obtain:
-
- 1st loop:
- ecx=(N1+S1-2)/2+1
- edx=(N2-2)
- and ecx=edx <=> (N1+S1-2)/2+1=N2-2 <=> N1+S1-2=2*(N2-3)
- and finally, as we want to know the serial :
- S1 = 2*(N2-3)-N1+2 = 2*(N2-2)-N1
-
- and we're even able to make a general formula:
-
- For i=1 to len(TName)-1
- S(i) = 2*[N(i+1) -2]-N(i)
- Next i
-
- this formula isn't applied to the last character of the name because N(i)
- exists but not N(i+1) bacause there are no char after the last character (
- besides, it wouldn't be the last char if there were one after :)
-
- We can now apply the formula to all the characters of 'SIFLYING'.
- We have first to convert the string to N1N2N3N4N5N6N7N8 (in decimalbase):
-
- N1='S'=83 ; N2='I'=73 ; N3='F'=70 ; N4='L'=76
- N5='Y'=89 ; N6='I'=73 ; N7='N'=78 ; N8='G'=71
-
- We have all what is necessary to calculate the S1S2S3S4S5S6S7 chars
- which compose serial for 'SiFLyiNG'. (the last char S8 will be calculated
- later ...)
-
- S1 = 2*(N2-2)-N1 = 2*(73-2)-83 = 59 = ';'
- S2 = 2*(N3-2)-N2 = 2*(70-2)-73 = 63 = '?'
- S3 = 2*(N4-2)-N3 = 2*(76-2)-70 = 78 = 'N'
- S4 = 2*(N5-2)-N4 = 2*(89-2)-76 = 98 = 'b'
- S5 = 2*(N6-2)-N5 = 2*(73-2)-89 = 53 = '5'
- S6 = 2*(N7-2)-N6 = 2*(78-2)-73 = 79 = 'O'
- S7 = 2*(N8-2)-N7 = 2*(71-2)-78 = 60 = '<'
-
- But S8 is missing... nope... come back to SoftIce and go on tracing...
- just after the previous loop you find this code :
-
- :00401288 movsx edx, byte ptr [ecx+eax] ;edx=value the last char of TName
- :0040128C movsx edi, byte ptr [eax+01] ;edi=value of 2nd char of TName
- :00401290 mov eax, dword ptr [esp+14] ;eax points to the entered serial
- :00401294 add edi, FFFFFFFE ;edi=edi-2
- :00401297 movsx eax, byte ptr [ecx+eax] ;value of last char of entered serial
- :0040129B lea eax, dword ptr [eax+edx-02] ;eax=eax+edx-2
- :0040129F cdq ;converts dword to quadword and edx=0
- :004012A0 sub eax, edx ;eax=eax-edx=eax
- :004012A2 sar eax, 1 ;eax=eax/2
- :004012A4 inc eax ;eax=eax+1
- :004012A5 cmp eax, edi ;eax and edi must be equal
- :004012A7 sete dl ;dl=1 if equal (0 if bad guy)
- :004012AA mov byte ptr [ecx+esi], dl ;stores dl in the array
-
- Hummm...it looks like the previous loop, doesn't it ? But this time
- it's no loop but the check of the last character of the entered serial.
-
- We have :
-
- eax= (ASCII code of last char of TName + ASCII code of last char of
- entered serial - 2) / 2 + 1
- edi= ASCII code of second char - 2
-
- ...and eax must be equal to edi to get dl=1. So here we got:
-
- (N8+S8-2)/2+1=N2-2 <=> S8 = 2*(N2-3)+2-N8 = 2*(N2-2)-N8
-
- and if we apply this we get:
-
- S8 = 2*(73-2)-71 = 71 = 'G'
-
- If we trace on in SoftIce, we'll arrive in the checking proc which
- check all the values that were stored in the array. Remember these lines:
- :00401278 mov byte ptr [ecx+esi], al ;stores al in an array
- and :004012AA mov byte ptr [ecx+esi], dl ;stores dl in the array
-
- where al (or dl for the last char) contains the result of the checking for
- each char of the Serial and are stored in [esi+ecx] where ecx is the counter
- and esi points to the array. The final part of the checking compares each
- value to 1. If one of them is 0, which means that the caracter of the serial
- was bad, then bl is set to 1 and it will jump at 4012D5. I'll let the code
- so that you can see by yourself the final comparison loop:
-
- :004012AD mov eax, dword ptr [esp+10]
- :004012B1 xor dl, dl
- :004012B3 xor bl, bl
- :004012B5 mov eax, dword ptr [eax-08]
- :004012B8 xor ecx, ecx
- :004012BA test eax, eax
- :004012BC jle 00401319
-
- Here begins the loop :
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004012CD(C)
- |
- :004012BE cmp byte ptr [ecx+esi], 00
- :004012C2 je 004012C8 ;jump if bad char and if flag=0
- :004012C4 mov dl, 01 ;dl=1 and i'll jump to bad cracker at 4012D1
- :004012C6 jmp 004012CA
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004012C2(C)
- |
- :004012C8 mov bl, 01 ;bl=1 and i'll jump to bad cracker at 4012D5
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004012C6(U)
- |
- :004012CA inc ecx ; increase the counter
- :004012CB cmp ecx, eax ; are all value checked ?
- :004012CD jl 004012BE ; if no, then jump
- :004012CF test dl, dl ; is dl=1 ?
- :004012D1 je 00401319 ; if yes, jump to bad cracker
- :004012D3 test bl, bl ; is bl=1 ?
- :004012D5 jne 00401319 ; if yes then jump to bad cracker
- :004012D7 Call 004016B2
- :004012DC push 00000066
- :004012DE push 0000000E
- :004012E0 push 00000066
- :004012E2 Call 004016AC
- :004012E7 push eax
-
- * Reference To: USER32.LoadIconA, Ord:019Eh
- |
- :004012E8 Call dword ptr [004021BC] ;load the smiling icon
-
- Hey if the smiling icon is loaded, it means that we found the correct
- serial for the name :)
- And crackme is cracked...
- So the serial for 'SiFLyiNG' or 'SIFLYING' or '--=<SiFLyiNG>=--' is:
- ';?Nb5O<G'
-
- ____________________________________________________________________________
-
- The end...
-
- I hope you have followed me til here... if not try to read this again
- and if you finally have questions, critics, or anything else, just mail me. I
- know this tutorial is quite long, but if you look closer, you'll see that
- it's really not difficult... it just applies the formula. Now try to make a
- keygen (use the formula and remember the transformations on the name...). I
- have included mine in VB5 with this tut and the EXE too... You'll see by
- yourself.
- Regards,
-
- SiFLyiNG
- siflying@ifrance.com
-
- Greetings: ACiD BuRN, Eternal Bliss, Skymarshall, Lucifer48, Carpathia
- and all the authors of crackmes and tutorials...
- and VisionZ for his crackme of course
-
-
-
-
-
-
-
-
-
-